/********************************************************************************
 * Project Name		[JavaSE_Fundamentals]
 * File Name     	[TestArrayList.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package collections;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/**
 * 集合框架 - java.util.ArrayList
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
public class TestArrayList {

	/**
	 * 创建ArrayList<br/>
	 */
	@SuppressWarnings("unused")
	public static void createList() {
		// 创建一个默认大小为的list
		// jdk 1.7 之前直接创建一个大小为10的list
		// jdk 1.7 之后默认创建一个大小为0的list, 第一次添加元素时容量增加到10
		ArrayList<String> list1 = new ArrayList<>();
		list1.add("element1");

		// 创建一个指定大小的list
		ArrayList<String> list2 = new ArrayList<String>(10);

		// 使用另外一个list来创建新的list
		ArrayList<String> list3 = new ArrayList<String>(list1);

		// 增加list3的容量
		list3.ensureCapacity(10);
	}

	/**
	 * ArrayList的增删改查方法
	 */
	public static void listCRUD() {
		ArrayList<String> list1 = new ArrayList<String>();
		// 增加元素
		list1.add("element1");
		list1.add(1, "element2");
		list1.add("element3");

		// 删除元素
		list1.trimToSize(); // 去掉多余的空元素
		list1.remove(1); // 删除指定索引的元素
		list1.remove("element3"); // 删除指定的元素
		list1.removeAll(new ArrayList<String>()); // 删掉指定的所有元素
		list1.clear(); // 清空list

		list1.add(0, "element2");
		list1.add(1, "element4");
		// 修改元素
		list1.set(0, "new element");

		// 查询元素
		String str = list1.get(0);
		list1.contains("element4"); // contains基于equals()
		System.out.println(str);
	}

	/**
	 * ArrayList的其他方法
	 */
	public static void otherMethods() {
		ArrayList<String> list1 = new ArrayList<String>();
		list1.add("element1");
		list1.add("element2");
		list1.add("element3");

		// 查看list是否包含指定元素
		System.out.println("list1是否包含element1: " + list1.contains("element1"));

		// 查看list的大小
		System.out.println("list1 的大小: " + list1.size());

		// 判断list是否为空
		System.out.println("list1 是否为空: " + (list1.isEmpty() ? "是" : "否"));

		ArrayList<String> list2 = new ArrayList<String>();
		list2.add("element3");

		// 查看list是否包含指定的集合
		System.out.println("list1是否包含集合list2: " + list1.containsAll(list2));

		// 保留list1和list2的共有元素
		list1.retainAll(list2);

		// 将list转换为数组
		String[] strArray = new String[list1.size()];
		strArray = list1.toArray(strArray);
		System.out.println("转换为数组后数组的大小 = " + strArray.length);

		ArrayList<String> list3 = new ArrayList<String>();
		list3.add("element1");
		list3.add("element2");
		list3.add("element3");
		list3.add("element4");
		list3.add("element5");

		// 截取子list
		@SuppressWarnings("unused")
		List<String> list4 = list3.subList(1, 3);
	}

	/**
	 * 迭代输出
	 * 
	 * @param list
	 */
	public static void iteratorList1(List<String> list) {
		// 使用Iterator迭代器
		Iterator<String> iter1 = list.iterator();
		while (iter1.hasNext()) {
			System.out.print(iter1.next() + "\t");
		}

		for (Iterator<String> iter2 = list.iterator(); iter2.hasNext();) {
			System.out.print(iter2.next() + "\t");
		}

		// 使用forEach
		for (String str : list) {
			System.out.print(str + "\t");
		}

		// 使用for循环, get(index)方式效率很低
		for (int i = 0; i < list.size(); i++) {
			System.out.print(list.get(i) + "\t");
		}
	}

	/**
	 * 迭代输出 - 使用ListIterator可以正向/反向遍历<br/>
	 * 
	 * 迭代器在遍历集合时的注意事项:<br/>
	 * 1. 在迭代器迭代元素的过程中, 不允许使用集合对象自身的CRUD方法, 如果需要添加或者删除只能使用迭代器的方法进行操作<br/>
	 * 2. 使用集合对象自身的CRUD方法会出现ConcurrentModificationException异常<br/>
	 * 3. 迭代元素的过程: 迭代器创建到使用结束的过程<br/>
	 * 
	 * @param list
	 */
	public static void iteratorList2(List<String> list) {
		ListIterator<String> iter = list.listIterator();

		// 正向遍历
		while (iter.hasNext()) {
			System.out.print("index" + iter.nextIndex() + "=" + iter.next() + "\t");
		}
		System.out.println();

		// 反向遍历, 这里不需要再次获取迭代器, 否则游标将会从0开始
		while (iter.hasPrevious()) {
			System.out.print("index" + iter.previousIndex() + "=" + iter.previous() + "\t");
		}
		System.out.println();
	}

	public static void main(String[] args) {
		createList();
		listCRUD();
		otherMethods();

		ArrayList<String> list = new ArrayList<String>();
		list.add("element1");
		list.add("element2");
		list.add("element3");
		list.add("element4");
		list.add("element5");

		iteratorList2(list);
	}
}
